<?php
//$Id: upload.php 159 2012-01-20 06:47:12Z tomqin@gmail.com $

/**
 * Upload 文件上传类
 *
 * @copyright		Copyright (C) 2010-2012 ARESCMS Inc.
 * @author			TomQin <tomqin@gmail.com>
 * @license			http://www.arescms.cn/license/
 * @package Core
 */

define('UPLOAD_ERR_FILE_SIZE',  10);
define('UPLOAD_ERR_FILE_TYPE',  11);
define('UPLOAD_ERR_IMAGE_TYPE', 12);
define('UPLOAD_ERR_IMAGE_SMALL',13);
define('UPLOAD_ERR_IMAGE_LARGE',14);
define('UPLOAD_ERR_UNKNOWN',	99);

class Upload {

	/**
	 * 上传的文件信息 $_FILES['upfile']
	 *
	 * @var array
	 */
	public $file = null;

	/**
	 * Upload类的配置信息
	 *
	 * 具体配置项说明
	 * - min_length (integer): 允许最小长度(字节)；默认值为 0
	 * - max_length (integer): 允许最大长度(字节)；0 为无限制
	 * - allow_type (string): 可以取文件名后缀，如：'txt|pdf|docx'；若为图片，可使用
	 *						image 代替 'jpeg|jpg|jpge|gif|png'
	 * - check_image (boolean): 是否检测图片，若为 true 会返回图片相关信息
	 * - image_min_width (integer): 允许图片的最小宽度（像素）
	 * - image_max_width (integer): 允许图片的最大宽度（像素）
	 * - image_min_height (integer): 允许图片的最小高度（像素）
	 * - image_max_height (integer): 允许图片的最大高度（像素）
	 *
	 * @var array
	 */
	private $options = array();

	/**
	 * Upload类的默认配置信息
	 *
	 * @see $options
	 * @var array
	 */
	private $default_options = array(
		'min_length'  => 0,
		'max_length'  => 0,
		'allow_type'  => 'image',
		'check_image' => false,
		'image_min_width'  => 0,
		'image_max_width'  => 10000,
		'image_min_height' => 0,
		'image_max_height' => 10000,
	);

	/**
	 * 构造函数
	 *
	 * @param string	上传文件信息，仅支持单文件。如 $_FILES['upfile']
	 * @param array		类的配置信息
	 * @param array		错误信息列表
	 */
	public function __construct($file, $options = array(), $errmsg = array()) {
		if(isset($_FILES[$file]))
			$this->file = $_FILES[$file];

		foreach($this->default_options as $key=>$var) {
			$this->options[$key] = isset($options[$key]) ? $options[$key]
				: $this->default_options[$key];
		}
	}

	/**
	 * 上传文件，返回错误信息
	 *
	 * @return integer	文件上传错误
	 */
	public function uploadFile() {
		$this->file['error'] = $this->checkUpload();
		return $this->file['error'];
	}

	/**
	 * 检查上传文件是否出错
	 *
	 * @return integer	文件上传错误
	 */
	private function checkUpload() {
		if(!isset($this->file)) {
			return UPLOAD_ERR_NO_FILE;
		}

		if($this->file['error']) {
			return $this->file['error'];
		}

		if(empty($this->file['tmp_name']) || empty($this->file['size'])) {
			return UPLOAD_ERR_NO_FILE;
		}

		//文件尺寸
		if($this->options['max_length'] > 0 && $this->file['size'] > $this->options['max_length']) {
			return UPLOAD_ERR_FILE_SIZE;
		}

		//文件类型
		if($this->options['allow_type']) {
			$fileext = strtolower(pathinfo($this->file['name'], PATHINFO_EXTENSION));

			$allow_type = ($this->options['allow_type'] == 'image') ? 'jpeg|jpg|jpge|gif|png' : $this->options['allow_type'];
			if(!preg_match("/{$allow_type}/i", $fileext)) {
				return UPLOAD_ERR_FILE_TYPE;
			}
		}

		//检查图片尺寸
		if($this->options['check_image']) {
			return $this->checkImage();
		}

		return UPLOAD_ERR_OK;
	}

	/**
	 * 检查上传图片是否出错
	 *
	 * @return integer	图片上传错误
	 */
	private function checkImage() {
		$this->file['imageinfo'] = getimagesize($this->file['tmp_name']);
		if(!$this->file['imageinfo']) {
			return UPLOAD_ERR_IMAGE_TYPE;
		} else {
			if($this->options['check_image']) {
				list($width, $height, $type, $attr) = $this->file['imageinfo'];
				if($width  < $this->options['image_min_width'] ||
				   $height < $this->options['image_min_height'])
				{
					return UPLOAD_ERR_IMAGE_SMALL;
				}

				if($width  > $this->options['image_max_width'] ||
				   $height > $this->options['image_max_height'])
				{
					return UPLOAD_ERR_IMAGE_LARGE;
				}
			}
		}

		return UPLOAD_ERR_OK;
	}

	public function getError($no) {
		$error = array(
			UPLOAD_ERR_OK		 => '文件上传成功', //0
			UPLOAD_ERR_INI_SIZE   => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',	//1
			UPLOAD_ERR_FORM_SIZE  => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
			UPLOAD_ERR_PARTIAL	=> 'The uploaded file was only partially uploaded.',
			UPLOAD_ERR_NO_FILE	=> '没有文件上传',
			UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
			UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
			UPLOAD_ERR_EXTENSION  => 'A PHP extension stopped the file upload.',

			UPLOAD_ERR_FILE_SIZE  => 'UPLOAD_ERR_FILE_SIZE',
			UPLOAD_ERR_FILE_TYPE  => 'UPLOAD_ERR_FILE_TYPE',
			UPLOAD_ERR_IMAGE_TYPE => 'UPLOAD_ERR_IMAGE_TYPE',
			UPLOAD_ERR_IMAGE_SMALL=> 'UPLOAD_ERR_IMAGE_SMALL',
			UPLOAD_ERR_IMAGE_LARGE=> 'UPLOAD_ERR_IMAGE_LARGE',

			UPLOAD_ERR_UNKNOWN	=> 'UPLOAD_ERR_UNKNOWN',
		);

		if(isset($error[$no]))
			return $error[$no];
		else
			return $error[UPLOAD_ERR_UNKNOWN];
	}
}
?>